-
Notifications
You must be signed in to change notification settings - Fork 69
[Feature] Add a configuration option to transform props coming from Inertia #254
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: master
Are you sure you want to change the base?
Conversation
### `prop_transformer` | ||
|
||
**Default**: `->(props:) { props }` | ||
|
||
Use `prop_transformer` to apply a transformation to your props before they're sent to the view. One use-case this enables is to work with `snake_case` props within Rails while working with `camelCase` in your view: | ||
|
||
```ruby | ||
inertia_config( | ||
prop_transformer: lambda do |props:| | ||
props.deep_transform_keys { |key| key.to_s.camelize(:lower) } | ||
end | ||
) | ||
``` | ||
|
||
> [!NOTE] | ||
> This controls the props provided by Inertia Rails but does not concern itself with props coming _into_ Rails. You may want to add a global `before_action` to `ApplicationController`: | ||
|
||
```ruby | ||
before_action :underscore_params | ||
|
||
# ... | ||
|
||
def underscore_params | ||
params.deep_transform_keys! { |key| key.to_s.underscore } | ||
end | ||
``` |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This probably needs work. Open to suggestions!
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I would drop this additional section about input props tbh, this configuration option is not only about casing, so it looks misplaced to me
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I see where you're coming from, but I think it's very likely that prop casing is the principal usage of this feature. I can try adjusting the wording to be a little more generic but it makes sense to me to highlight the transformation isn't bidirectional
merge_props(shared_data, props) | ||
# This performs the internal work of hydrating/filtering props | ||
.then { |props| deep_transform_props(props) } | ||
# Then we apply the user-defined prop transformer | ||
.then { |props| configuration.prop_transformer(props: props) } | ||
# Then we add meta tags after everything since they must not be transformed | ||
.tap { |props| props[:_inertia_meta] = meta_tags if meta_tags.present? } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This order ensures that any current or future internal props (like _inertia_meta
) are untouched by the user-provided transformer. As long as they're added later in the chain than the call to prop_transformer
, they're good to go
@@ -0,0 +1,32 @@ | |||
# frozen_string_literal: true | |||
|
|||
class InertiaPropTransformerController < ApplicationController |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I was kind of winging it with this. Open to feedback!
Resolves #247
Let me know what you think!